package com.iot08.api.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iot08.api.config.redis.RedisClusterService;
import com.iot08.api.service.*;
import com.iot08.api.service.supplement.KafkaService;
import com.iot08.api.utils.SpringContextUtil;
import com.iot08.api.vo.request.Dev_HCYPhotoReqVO;
import com.iot08.api.vo.request.HCYAuthReqVO;
import com.iot08.common.constant.ConstCacheField;
import com.iot08.common.constant.ConstKafka;
import com.iot08.common.entity.app.*;
import com.iot08.common.utils.*;
import com.iot08.common.utils.response.ResponseEnum;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.Date;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("getway/hcy/")
public class HCYAccountController {


    @Resource
    private RedisClusterService redisClusterService;

    @Resource
    private DevHCYAuthService devHCYAuthService;

    @Resource
    private FamilyHCYAuthService familyHCYAuthService;

    @Resource
    private HCYAuthLogService hcyAuthLogService;

    @Resource
    private DeviceService deviceService;

    @Resource
    private KafkaService kafkaService;

    /************************* 和彩云相册接口接口 **********************/

    /**
     * 查询设备云相册授权信息
     * @param imei
     * @param vo
     * @param bindingResult
     * @time: 12/17/22 5:22 PM
     * @author: Weichao
     * @version 1.0
     */
    @GetMapping("/{imei}/hcy-photosAuthorizationInfo")
    public ResponseMap getHCY_PhotosAuthorizationInfo(@PathVariable("imei") String imei,
                                                      @RequestHeader(value = "uuid", required = false) String uuid,
                                                      @RequestHeader(value = "User-Agent", required = false) String userAgent,
                                                      @Validated Dev_HCYPhotoReqVO vo, BindingResult bindingResult, String curFamilPhone) {
        //请求头数据解析处理
        // 0:web 1:Android 2:iOS
        int isQType = 0;
        if (StringUtil.isNotBlank(userAgent)) {
            if (userAgent.contains("Android")) {
                isQType = 1;
            } else if (userAgent.contains("iOS")) {
                isQType = 2;
            }
        }

        JSONObject resOB = new JSONObject();
        //查询家长 是否授权手表使用云相册

        DevHCYAuth devHCYAuth = devHCYAuthService.findById(imei);
        if(curFamilPhone == null){
            //当前家长请求的授权登录的手机号
            Device dev = deviceService.findById(imei);
            Map<String, Object> familOB = dev.getUserMap().get(vo.getOpenid());
            curFamilPhone = familOB.getOrDefault("phone", "").toString();
            log.info("imei:{} 家长openid:{} curFamilPhone:{} 查询设备云相册授权信息", imei, vo.getOpenid(), curFamilPhone);
        }else{
            log.info("imei:{} 接口内调用 curFamilPhone:{}", imei, curFamilPhone);
        }


        int res = 2;
        FamilyHCYAuth familyHCYA = null;
        /*
        -3: 云相册 不存在, 可能是家庭群被删了

        -2: 设备未开通云相册 , APP可以点击按钮调用 hcy-notificationDev(APP家长通知手表重新登录 和彩云相册接口)

        -1: 设备关闭相册

        0: 家长未授权手表使用时, 这个时候APP需要弹框UI提示 ,确认后调用 hcy-photosAuth (授权设备使用云相册)

        1: 已授权手表使用,但是家长自己(UUID)没授权(或者是accesstoken已经失效), 拿到返回值后:

        ​	访问**authPageUrl**

        ​	访问授权成功后移动平台回调回调地址(应该是我们自己的H5 页面)

        ​	APP监测页面链接跳转到自己的H5页面后 ,用**authUUID** 请求 **hcy-tempPageAuthSuccess**

            接口然后根据返回参数跳转到的对应的链接(后台服务单点登录过的可用的单点登录路径URL) 云相册H5

        2: 已授权手表使用,家长自身accesstoken也未失效

        根据返回参数跳转到的对应的链接(后台服务单点登录过的可用的单点登录路径URL) 云相册H5
        */
        if(devHCYAuth != null){
            if(devHCYAuth.getIsOff() == 1){
                //设备相册关闭
                res = -1;
            }else if (devHCYAuth.getFamily_auth() == 0) {
                // 家长未授权手表使用时, 这个时候APP需要弹框UI提示 ,确认后调用 hcy-photosAuth (授权设备使用云相册)
                res = 0;
            }else if (StringUtil.isBlank(devHCYAuth.getCloudID())|| StringUtil.isBlank(devHCYAuth.getAlbumld())){
                //没有相册ID
                res = -2;
            }else{
                // String family_auth_uuid = devHCYAuth.getFamily_auth_uuid();
                String family_auth_uuid = vo.getOpenid();
                if(family_auth_uuid != null){
                    familyHCYA = familyHCYAuthService.findById(family_auth_uuid+"&"+devHCYAuth.getProject_type()+"&"+curFamilPhone);
                    if(familyHCYA != null){
                        String hcy_accesstoken = familyHCYA.getHcy_accesstoken();
                        Long hcy_accesstoken_expiry = familyHCYA.getHcy_accesstoken_expiry();
                        Long nowTime = DateUtil.nowTimestampToLong();
                        String famil_token = hcy_accesstoken;
                        if(hcy_accesstoken == null || (nowTime >= hcy_accesstoken_expiry)){
                            //家长授权过期
                            res = 1;
                        }else{
                            //如果在 有效期内刷新Token
                            famil_token = familyHCYAuthService.familyHCYRefreshToken(imei, family_auth_uuid, familyHCYA);

                            if(famil_token != null){
                                res = 2; //一切正常,单点登录得 云相册H5访问链接
                                if( vo.getWillOpenHCYH() == 1 ){
                                    if(StringUtil.isBlank(devHCYAuth.getCloudID())|| StringUtil.isBlank(devHCYAuth.getAlbumld())){
                                        return ResponseMap.fail("错误,设备无家庭云相册");
                                    }
                                    //检查是否在云相册里面
                                    int checkRes = familyHCYAuthService.getThisFamilyIsInHCYAlbum(familyHCYA, devHCYAuth.getCloudID(), devHCYAuth.getAlbumld(), imei, isQType);
                                    if(checkRes == 0){ //不在其中
                                        //自动加入云相册
                                        int b = familyHCYAuthService.postFamilyAutoJoinCloudId(devHCYAuth, familyHCYA, imei, isQType);
                                        if(b != 0){
                                            if(b == -2){
                                                return ResponseMap.fail("自动加入云相册失败");
                                            }else if(b == -1){
                                                res = 1; //accesstoken 失效
                                            }

                                        }
                                    }else if(checkRes < 0){
                                        if(checkRes == -1){
                                            res = 1; //accesstoken 失效
                                        }else if(checkRes == -3){
                                            //云相册 不存在, 可能是家庭群被删了
                                            log.error("imei:{} 云相册 不存在, 可能是家庭群被删了", imei);
                                            res = -3;
                                        }else{
                                            return ResponseMap.fail("进入云相册检查失败 errorCode:"+checkRes);
                                        }

                                    }
                                }

                            }

                        }
                    }else{
                        //没有家长uuid就是没有授权
                        res = 1;
                    }

                }else{
                    //没有家长uuid就是没有授权
                    res = 1;
                }
            }

        }else{
            res = 0;
            log.info("imei:{} 找不到记录,未授权", imei);
        }

        if( vo.getWillOpenHCYH() == 1 ){
            if(devHCYAuth != null && res == 2){
                try{
                    //默认是秒,变成毫秒需 * 1000
                    Long family_auth_time = devHCYAuth.getFamily_auth_time()*1000;
                    String timeStr = DateUtil.stampToDateStr(family_auth_time, DateUtil.FORMAT_1);
                    //云相册设置页URL
                    resOB.put("hcyAlbumSettingURL", "https://api.device.iot08.com/getway/hcyAlbumSetting?time="+URLEncoder.encode(timeStr,"UTF-8"));
                }catch (Exception e){
                    log.error("云相册设置页URL获取失败", e);
                }

            }
            if(res == 1) {
                //授权已经失效 返回授权参数 authPageUrl 和 authUUID
                resOB.put("status", res);
                //生成授权页面请求地址
                //拼接中间页
                String redirectUrl = devHCYAuthService.HCYAuthBackTemp_H5URL ; //APP请求的这里需填我们服务器自有的Html的回调地址 (移动中间页跳转后,APP需检测)
                // 请求ID :base64（appid_yyyyMMddHHmmssSSS+3位随机数）生成。登录成功后用于换取开放平台接口调用所需的唯一凭证accesstoken。
                String qId = String.format("%s_%s%s", devHCYAuthService.getAppID(devHCYAuth), DateUtil.dateToStr(new Date(), "yyyyMMddHHmmssSSS"), RandomUtil.getRandom(100,999));
                String qIdBase64Str = new String(Base64.getEncoder().encode(qId.getBytes()));
                try{
                    //APP端 如果使用半屏 可以使用 halfScreen=1&authHeight=50px halfScreen:1 半屏 authHeight:授权页面高度
                    String  urlParam = String.format("?pageType=3&appId=%s&appKey=%s&appTitle=%s&deviceId=%s&uuid=%s&mobile=%s&channelId=%s&redirectUrl=%s",
                            devHCYAuthService.getAppID(devHCYAuth),
                            devHCYAuthService.getAppKey(devHCYAuth),
                            devHCYAuthService.getAppTitle(devHCYAuth),
                            vo.getOpenid(),
                            URLEncoder.encode(qIdBase64Str,"UTF-8"), //此参数用户换取token //单独 URL编码一下
                            curFamilPhone,
                            devHCYAuthService.HCYDevChannelId,
                            URLEncoder.encode(redirectUrl,"UTF-8")//单独 URL编码一下
                    );

                    String middlePageUrl = devHCYAuthService.HCYMiddlePageURL + urlParam;
                    resOB.put("authPageUrl", middlePageUrl);
                    resOB.put("authUUID", qIdBase64Str);
                    return ResponseMap.success(resOB);
                }catch (Exception e){
                    log.error("可能编码失败 imei:"+imei+ "openid:"+vo.getOpenid(), e);
                    return ResponseMap.fail("获取授权页有误");
                }

            } else if(res == 2){
                //单点授权后返回对应 授权过的H5 云相册 登录连接
                String authHCY_h5URL = familyHCYAuthService.getAuthHCY_H5URL(devHCYAuth, familyHCYA, isQType);
                if(authHCY_h5URL != null){
                    //表示此 uuid 读过
                    String hcyPhotosUnreadListStr = devHCYAuth.getHcyPhotosUnreadListStr();
                    if(hcyPhotosUnreadListStr != null && hcyPhotosUnreadListStr.length() > 2){
                        JSONArray unreadList = JSONArray.parseArray(hcyPhotosUnreadListStr);
                        if(unreadList.contains(uuid)){
                            //未读的用户里存在当前用户, 表示读过后要移除
                            unreadList.remove(uuid);
                            if (unreadList.size() == 0){
                                devHCYAuth.setHcyPhotosUnreadListStr(null);
                            }else{
                                devHCYAuth.setHcyPhotosUnreadListStr(unreadList.toJSONString());
                            }

                            devHCYAuthService.save(devHCYAuth);
                        }

                    }
                    //生成授权页面请求地址
                    resOB.put("hcyAlbumURL", authHCY_h5URL);
                    resOB.put("status", res);
                    return ResponseMap.success(resOB);
                }else{
                    //云相册 家长 单点登录失败
                    res = 1;
                }

            } else if(res == -1){
                //设备相册关闭, 返回关闭页面
                resOB.put("hcyAlbumCloseURL", "https://api.device.iot08.com/getway/hcyAlbumClose");
            }
        }

        resOB.put("status", res);
        String activeProfile = SpringContextUtil.getActiveProfile();
        if(activeProfile.contains("dev")){
            log.info("环境:{} imei:{} resOB:{}",activeProfile, imei, resOB.toJSONString());
        }
        return ResponseMap.success(resOB);

    }



    /**
     * APP家长授权设备使用云相册
     * @param imei
     * @param vo
     * @param bindingResult
     * @time: 12/17/22 5:22 PM
     * @author: Weichao
     * @version 1.0
     */
    @PostMapping("/{imei}/hcy-photosAuth")
    public ResponseMap postHCY_PhotosAuth(@PathVariable("imei") String imei,
                                          @Validated Dev_HCYPhotoReqVO vo, BindingResult bindingResult){
        Device dev = deviceService.findById(imei);
        if(dev == null) {
            return ResponseMap.fail(ResponseEnum.STATUS2001.getCode(), ResponseEnum.STATUS2001.getMsg() + imei);
        }
        if(vo.getOpenid() == null){
            return ResponseMap.fail("参数缺失");
        }
        DevHCYAuth devHCYAuth = devHCYAuthService.findById(imei);
        if(devHCYAuth == null){
            devHCYAuth = new DevHCYAuth();
            devHCYAuth.setId(imei);
            if(dev.getWatchCustomFunction() != null){
                if(dev.getWatchCustomFunction().contains("NIUMAN")){
                    devHCYAuth.setProject_type(0);
                }else if (dev.getWatchCustomFunction().contains("XIAOXUN")) {
                    devHCYAuth.setProject_type(1);
                }else if (dev.getWatchCustomFunction().contains("YDYP_NRX")){
                    //诺而信
                    devHCYAuth.setProject_type(2);
                }else{
                    return ResponseMap.fail("设备找不到对应配置,授权有误");
                }
            }else{
                return ResponseMap.fail("设备自定义配置,授权有误");
            }

            devHCYAuth.setCreatDate(new Date());
        }
        devHCYAuth.setFamily_auth(1);
        devHCYAuth.setFamily_auth_time(DateUtil.nowTimestampToLong());
        devHCYAuth.setFamily_auth_uuid(vo.getOpenid());
        Map<String, Object> familOB = dev.getUserMap().get(vo.getOpenid());
        devHCYAuth.setFamily_auth_relationship(familOB.get("relationship").toString());
        devHCYAuth.setFamily_auth_phone(familOB.getOrDefault("phone", "").toString());
        devHCYAuth.setUpdateDate(new Date());
        devHCYAuthService.save(devHCYAuth);

        //授权过要加入 记录
        FamilyHCYAuth familyHCYAuth = new FamilyHCYAuth();
        familyHCYAuth.setId(vo.getOpenid()+"&"+devHCYAuth.getProject_type()+"&"+familOB.getOrDefault("phone", "").toString());
        familyHCYAuth.setProject_type(devHCYAuth.getProject_type());
        familyHCYAuth.setPhone(familOB.getOrDefault("phone", "").toString());
        familyHCYAuth.setCreatDate(new Date());
        familyHCYAuthService.save(familyHCYAuth);


        //添加日志记录
        HCYAuthLog hcyAuthLog = new HCYAuthLog();
        hcyAuthLog.setId(UUIDGenerator.generate());
        hcyAuthLog.setImei(imei);
        hcyAuthLog.setFamilyUUID(vo.getOpenid());
        hcyAuthLog.setFamilyPhone(familOB.getOrDefault("phone", "").toString());
        //授权类型:
        // 0:家长授权 1:设备自己登录授权 2:设备邀请加入云相册
        // 3:家长自己登录授权 4:家长加入云相册
        hcyAuthLog.setType(0);
        hcyAuthLog.setCreatDate(new Date());
        hcyAuthLogService.save(hcyAuthLog);

        return ResponseMap.success();
    }



    /**
     * ### APP家长中间页授权成功后获取云相册链接
     *
     * APP在检测到 **家长在和彩云的中间页授权成功** 时,需要调用此接口得到:
     *
     * 对应的链接(后台服务单点登录过的可用的单点登录路径URL) 云相册H5 后进行跳转
     * @param imei
     * @param vo
     * @param bindingResult
     * @time: 12/24/22 11:55 AM
     * @author: Weichao
     * @version 1.0
     */
    @PostMapping("/{imei}/hcy-tempPageAuthSuccess")
    public ResponseMap postHCY_tempPageAuthSuccess(@PathVariable("imei") String imei,
                                                   @RequestHeader(value = "User-Agent", required = false) String userAgent,
                                                   @Validated Dev_HCYPhotoReqVO vo, BindingResult bindingResult){
        //请求头数据解析处理
        // 0:web 1:Android 2:iOS
        int isQType = 0;
        if (StringUtil.isNotBlank(userAgent)) {
            if (userAgent.contains("Android")) {
                isQType = 1;
            } else if (userAgent.contains("iOS")) {
                isQType = 2;
            }
        }

        //请求中间页时 授权的 uuid
        String authUUID = vo.getAuthUUID();
        if(authUUID == null || vo.getOpenid() == null){
            return ResponseMap.fail("参数缺失,失败");
        }
        JSONObject resOB = new JSONObject();

        //提交验证码成功 后这时候 用去请求才能获得token
        JSONObject getTokenParam = new JSONObject();
        getTokenParam.put("uuid", authUUID);
        String getTokenRes = HttpReq.sendPostJson(devHCYAuthService.HCYMiddlePageGetTokenURL, getTokenParam.toJSONString());
        JSONObject getTokenResOB = JSONObject.parseObject(getTokenRes);
        if(getTokenResOB.getInteger("code") == 0){
            /*
            {
                "code": 0,
                "message": "成功",
                "data": {
                    "accessToken": "123",
                    "expiresIn": 168
                }
            }
            */
            DevHCYAuth devHCYAuth = devHCYAuthService.findById(imei);
            //家长授权登录的手机号
            //得查一下
            Device dev = deviceService.findById(imei);
            Map<String, Object> familOB = dev.getUserMap().get(vo.getOpenid());
            String familPhone = familOB.getOrDefault("phone", "").toString();
            FamilyHCYAuth familyHCYAuth = familyHCYAuthService.findById(vo.getOpenid()+"&"+devHCYAuth.getProject_type()+"&"+familPhone);
            if(familyHCYAuth == null){
                //无则新建
                familyHCYAuth = new FamilyHCYAuth();
                familyHCYAuth.setCreatDate(new Date());
                familyHCYAuth.setId(vo.getOpenid()+"&"+devHCYAuth.getProject_type()+"&"+familPhone);
                familyHCYAuth.setProject_type(devHCYAuth.getProject_type());
                familyHCYAuth.setPhone(familPhone);
            }
            JSONObject data = getTokenResOB.getJSONObject("data");
            String newToken = data.getString("accessToken");
            Long nowTime = DateUtil.nowTimestampToLong();
            Long newTokenExpiresIn = nowTime + data.getInteger("expiresIn") * 3600;
            familyHCYAuth.setHcy_accesstoken(newToken);
            familyHCYAuth.setHcy_accesstoken_expiry(newTokenExpiresIn);
            familyHCYAuth.setHcy_accesstoken_update(new Date());
            familyHCYAuth.setUpdateDate(new Date());
            familyHCYAuthService.save(familyHCYAuth);
            // 成功获取到token 后:
            // 1.需要对是否加入相册进行检查
            // 2.进行单点授权 // 对应的链接(后台服务单点登录过的可用的单点登录路径URL) 云相册H5 后进行跳转

            //检查是否在云相册里面 -2:其他错误 -1: accesstoken失效  0:不在其中  1:在其中
            int checkRes = familyHCYAuthService.getThisFamilyIsInHCYAlbum(familyHCYAuth, devHCYAuth.getCloudID(), devHCYAuth.getAlbumld(), imei, isQType);
            if(checkRes == 0){
                //自动加入云相册 -2:其他错误 -1: accesstoken失效  0: 成功
                int b = familyHCYAuthService.postFamilyAutoJoinCloudId(devHCYAuth, familyHCYAuth, imei, isQType);
                if(b != 0){
                    return ResponseMap.fail("自动加入云相册失败 "+ b);
                }
            }else if(checkRes < 0){
                return ResponseMap.fail("进入云相册检查失败 checkRes:"+checkRes);
            }

            //单点授权后返回对应 授权过的H5 云相册 登录连接
            String authHCY_h5URL = familyHCYAuthService.getAuthHCY_H5URL(devHCYAuth, familyHCYAuth, isQType);
            if(authHCY_h5URL != null){
                resOB.put("hcyAlbumURL", authHCY_h5URL);
            }else{
                return ResponseMap.fail("单点授权失败");
            }

        }else{
            log.error("imei:{} 家长:{} 授权成功调用接口获取accesstoken 失败 getTokenRes:{}", imei, vo.getOpenid(), getTokenRes);
            return ResponseMap.fail("家长授权获取accesstoken失败");
        }


        return ResponseMap.success(resOB);
    }

    /**
     * 通知手表重新登录 和彩云接口
     * @param imei
     * @param vo
     * @param bindingResult
     * @time: 12/17/22 5:22 PM
     * @author: Weichao
     * @version 1.0
     */
    @PostMapping("/{imei}/hcy-notificationDev")
    public ResponseMap postHCY_JoinPhotos(@PathVariable("imei") String imei,
                                          @Validated Dev_HCYPhotoReqVO vo, BindingResult bindingResult){

        DevHCYAuth devHCYAuth = devHCYAuthService.findById(imei);
        if(devHCYAuth == null){
            return ResponseMap.fail("手表未授权云相册");
        }
        //得查一下
        Device dev = deviceService.findById(imei);
        Map<String, Object> familOB = dev.getUserMap().get(vo.getOpenid());
        if(familOB == null){
            return ResponseMap.fail();
        }
        //设备不在线不进行下发
        String onlineStatus = redisClusterService.hget(imei, ConstCacheField.ONLINE_STATUS);
        if (!"1".equals(onlineStatus)) {
            return ResponseMap.fail(ResponseEnum.STATUS5001.getCode(), ResponseEnum.STATUS5001.getMsg());
        }

        String relationship = familOB.getOrDefault("relationship", "").toString();

        JSONObject kafkaMsgOB = new JSONObject();
        kafkaMsgOB.put("msg", String.format("%s提醒手表登录云相册",relationship));
        kafkaMsgOB.put("status", 1);
        kafkaMsgOB.put("p_name", relationship);
        kafkaService.emitDeviceDemand(imei, ConstKafka.DEVICE_TYPE_HCY_Status, kafkaMsgOB, vo.getOpenid());
        return ResponseMap.success();
    }

}
